<template>
  <div v-if="isInput" class="pin pin-input" :style="pinStyle" @mousedown.stop>
    <span
      class="pin-icon"
      :id="pinId"
      :style="iconStyle"
      @mousedown.stop="handleIconMouseDown"
      @mouseup.stop="handleIconMouseUp"
    ></span>
    <span class="pin-title">{{ title }}</span>
    <template v-if="!hasLink">
      <input v-if="isBool" type="checkbox" :checked="value" @change="handleChange" />
      <input v-else-if="isString" type="text" :value="value" :style="inputStyle" @input="handleInput" />
      <input v-else-if="isInt" type="number" step="1" :value="value" :style="inputStyle" @input="handleInput" />
      <input
        v-else-if="isUInt"
        type="number"
        step="1"
        min="0"
        :value="value"
        :style="inputStyle"
        @input="handleInput"
      />
      <input v-else-if="isFloat" type="number" :value="value" :style="inputStyle" @input="handleInput" />
    </template>
  </div>
  <div v-else class="pin pin-output">
    <span class="pin-title">{{ title }}</span>
    <span
      class="pin-icon"
      :id="pinId"
      :style="iconStyle"
      @mousedown.stop="handleIconMouseDown"
      @mouseup.stop="handleIconMouseUp"
    ></span>
  </div>
</template>

<script>
import * as chroma from 'chroma-js';
import { mapState, mapMutations, mapGetters } from 'vuex';
const prototype = require('../prototype');

export default {
  props: ['isInput', 'nodeIndex', 'pinIndex', 'title', 'type', 'value'],

  methods: {
    ...mapMutations(['dragStart', 'changePinValue', 'addLinks', 'deleteLinks', 'moveLinks']),

    handleIconMouseDown(ev) {
      if (ev.altKey) {
        this.deleteLinks({ isInput: this.isInput, nodeId: this.nodes[this.nodeIndex].id, pinTitle: this.title });
      } else if (ev.ctrlKey) {
        this.moveLinks({
          isInput: this.isInput,
          nodeId: this.nodes[this.nodeIndex].id,
          pinTitle: this.title,
          x: ev.clientX,
          y: ev.clientY,
        });
        this.deleteLinks({ isInput: this.isInput, nodeId: this.nodes[this.nodeIndex].id, pinTitle: this.title });
      } else {
        this.dragStart({
          type: 'LINKS',
          x: ev.clientX,
          y: ev.clientY,
          links: [
            {
              isInput: this.isInput,
              nodeId: this.nodes[this.nodeIndex].id,
              pinTitle: this.title,
            },
          ],
        });
      }
    },

    handleIconMouseUp() {
      if (this.isLinking) {
        this.addLinks({ isInput: this.isInput, nodeId: this.nodes[this.nodeIndex].id, pinTitle: this.title });
      }
    },

    handleInput(ev) {
      this.changePinValue({
        nodeIndex: this.nodeIndex,
        pinIndex: this.pinIndex,
        value: ev.currentTarget.value,
      });
    },

    handleChange(ev) {
      this.changePinValue({
        nodeIndex: this.nodeIndex,
        pinIndex: this.pinIndex,
        value: ev.currentTarget.checked,
      });
    },
  },

  computed: {
    ...mapState(['nodes', 'links', 'linkingPins']),
    ...mapGetters(['isLinking']),

    hasLink() {
      return this.$store.getters.hasLink(this.isInput, this.nodes[this.nodeIndex].id, this.title);
    },

    pinId() {
      return `${this.isInput ? 'in' : 'out'}_${this.nodes[this.nodeIndex].id}_${this.title}`;
    },

    isBool() {
      return this.type === 'bool';
    },

    isInt() {
      return this.type.startsWith('int');
    },

    isUInt() {
      return this.type.startsWith('uint');
    },

    isFloat() {
      return this.type === 'float' || this.type === 'double';
    },

    isString() {
      return this.type === 'string';
    },

    iconStyle() {
      const color = prototype.typeColor(this.type);
      const chartsColor = `var(--vscode-charts-${color})`;
      return {
        backgroundColor: chroma.valid(chartsColor) ? chartsColor : color,
      };
    },

    inputStyle() {
      return {
        width: `${this.value.length + 1}ch`,
      };
    },

    pinStyle() {
      if (!this.value || typeof this.value === 'boolean') {
        return {};
      } else {
        return {
          flexWrap: this.value.toString().length > 8 ? 'wrap' : 'nowrap',
        };
      }
    },
  },
};
</script>

<style scoped>
.pin {
  display: flex;
  align-items: center;
}

.pin-input {
  justify-content: flex-start;
}

.pin-output {
  justify-content: flex-end;
}

.pin-title {
  color: var(--vscode-quickInput-foreground);
  margin-bottom: 5px;
  user-select: none;
  font-size: 0.7rem;
  margin-left: 5px;
  margin-right: 5px;
  text-align: center;
}

.pin-icon {
  margin-bottom: 5px;
  width: 10px;
  height: 10px;
  border-radius: 100%;
  border: thin solid var(--vscode-charts-lines);
  background-color: white;
  cursor: pointer;
}

input[type='text'],
input[type='number'] {
  margin-bottom: 5px;
  width: 2ch;
  min-width: 2ch;
  max-width: 150px;
}

input[type='checkbox'] {
  margin-bottom: 5px;
}
</style>
